Skip to content

feat(sdk): add opt-in stdin for detached commands - #365

Merged
kishorekrd merged 12 commits into
mainfrom
kishore/command-stdin
Oct 9, 2026
Merged

kishorekrd merged 12 commits into
mainfrom
kishore/command-stdin

Conversation

@kishorekrd

@kishorekrd kishorekrd commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Adds stdin for commands, mainly to run stdio MCP servers (like agent-browser mcp) in a sandbox.

const cmd = await sandbox.runCommand({ cmd: "cat", stdin: true, detached: true });
await cmd.writeStdin("hello\n");
await cmd.closeStdin();

// or pipe a stream, with or without detached
await sandbox.runCommand({ cmd: "agent-browser", args: ["mcp"], stdin: process.stdin, stdout: process.stdout });
  • stdin: true needs detached: true. A Readable is written in order with backpressure, and stdin closes when it ends. The caller's stream is never destroyed.
  • If piping fails, runCommand rejects and kills the command. When detached, the next wait() rejects instead.
  • Each request carries its stdin position, so retries on 429, 502, 503, 504 and network errors never duplicate bytes. If a write still fails, later writes are rejected, but closeStdin still works.
  • In workflows, step retries are off and each step continues from the server's position.
  • @vercel/sandbox-mock support is a follow-up.

Needs backend support that ships separately. The integration tests fail until it's deployed.

runCommand accepts `stdin: true` (detached only), and Command gains
writeStdin() and closeStdin(). Writes are serialized per command, split
into 512 KiB chunks, and never retried so bytes can't be delivered twice.
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
sandbox Ready Ready Preview, v0 Oct 9, 2026 6:54pm UTC
sandbox-cli Ready Ready Preview Oct 9, 2026 6:54pm UTC
sandbox-sdk-ai-example Ready Ready Preview Oct 9, 2026 6:54pm UTC
workflow-code-runner Ready Ready Preview Oct 9, 2026 6:54pm UTC

Request Review

Workflow DevKit retries failed steps by default, which could resend
stdin bytes, so writeStdin and closeStdin now run with maxRetries 0.
Rate limited writes are retried again since they were never applied.
A write that fails after possibly delivering data now blocks later
writes instead of appending to a partial message, an abort while
waiting in the queue takes effect, and CommandFinished rejects stdin
calls with a clear error.
Each workflow step gets a freshly deserialized Command, so the write queue and the rejection after a failed write don't carry across steps.
Each stdin request now carries the position it starts at, so a request that
fails on a dropped connection or a restarting server is resent without
delivering the same bytes twice. Timeouts are only resent while the process
keeps reading.
Passing a Readable such as process.stdin as `stdin` pipes it to the command
and closes stdin when it ends, with or without `detached`.
Comment thread packages/vercel-sandbox/src/command.ts
Comment thread packages/vercel-sandbox/src/command.ts Outdated
Comment thread packages/vercel-sandbox/src/utils/pipe-stdin.ts
@kishorekrd
kishorekrd enabled auto-merge (squash) October 9, 2026 18:56
@kishorekrd
kishorekrd merged commit 31244aa into main Oct 9, 2026
14 checks passed
@kishorekrd
kishorekrd deleted the kishore/command-stdin branch October 9, 2026 19:03
@github-actions github-actions Bot mentioned this pull request Oct 9, 2026
QuiiBz pushed a commit that referenced this pull request Oct 12, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## sandbox@4.8.0

### Minor Changes

- Add `sandbox create claude` to open Claude Code in a new Vercel
Sandbox. ([#371](#371))

- Add `sandbox create codex` to open Codex in a new Vercel Sandbox.
([#373](#373))

- Add `sandbox create opencode` to create a sandbox with the universal
image and open OpenCode directly in the terminal.
([#370](#370))

- Add `sandbox create pi` to open Pi in a Sandbox with scoped reconnect
and stop commands. ([#372](#372))

### Patch Changes

- Show a coding agent launch example first in the top-level CLI help.
([#378](#378))

- Update `@vercel/oidc` to v4.
([#375](#375))

- Updated dependencies
[[`515f60b261fd7fa2ae9e5ae58fb8d950e4378089`](515f60b),
[`31244aa3280dc3fdca0680933f85971570d73d2d`](31244aa)]:
  - @vercel/sandbox@3.7.0
## @vercel/sandbox@3.7.0

### Minor Changes

- Add opt-in stdin for commands. Pass `stdin: true` to a detached
`runCommand`, then use `command.writeStdin(data)` and
`command.closeStdin()` while it runs, or pass a `Readable` such as
`process.stdin` to have it piped to the command.
([#365](#365))

### Patch Changes

- Update `@vercel/oidc` to v4.
([#375](#375))
## @vercel/sandbox-mock@3.7.0

### Patch Changes

- Updated dependencies
[[`515f60b261fd7fa2ae9e5ae58fb8d950e4378089`](515f60b),
[`31244aa3280dc3fdca0680933f85971570d73d2d`](31244aa)]:
  - @vercel/sandbox@3.7.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
kishorekrd added a commit that referenced this pull request Oct 19, 2026
Every sandbox now supports stdin write offsets, so the SDK no longer
needs the fallbacks for ones that don't:

- `Command` always sends an offset, instead of switching to unsafe
writes when a response lacks `bytesWritten`. If it can't learn the
current offset, it fails before writing rather than assuming 0.
- A 504 no longer triggers an extra empty request to find the bytes
written; the timeout response already includes them.

<!-- project-ships:v1
{
"user_intent": "Finish the opt-in stdin rollout for Sandbox commands by
removing SDK compatibility code for sandboxes that predate stdin write
offsets, now that every sandbox supports them.",
"intended_outcome": "The @vercel/sandbox SDK always sends stdin offsets,
no longer probes for bytes written after a timeout, and fails loudly
instead of assuming offset 0 when the current offset is unknown.",
  "related_prs": ["#365"],
  "change_type": "chore"
}
-->

This branch was successfully deployed

4 active deployments
Preview – sandbox-sdk-ai-example — 2dca644a Deployed Oct 9, 2026 by vercel[bot]
Preview – workflow-code-runner — 2dca644a Deployed Oct 9, 2026 by vercel[bot]
Preview – sandbox — 2dca644a Deployed Oct 9, 2026 by vercel[bot]
Preview – sandbox-cli — 2dca644a Deployed Oct 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants